package kr.salebeans.cm.provider.point.impl;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import kr.salebeans.cm.domain.point.CustomerPoint;
import kr.salebeans.cm.domain.point.PointClsType;
import kr.salebeans.cm.provider.point.CustomerPointProvider;

public class CustomerPointProviderImpl implements CustomerPointProvider {

    @PersistenceContext
    private EntityManager em;

    @Override
    public CustomerPoint createCustomerPoint(CustomerPoint point) {
        em.persist(point);
        return point;
    }

    @Override
    public Map<Long, Long> retrieveCurrentCustomerListPoint(List<Long> customerIds) {
        StringBuilder qlString = new StringBuilder();
        qlString.append(" SELECT cp ");
        qlString.append("   FROM CustomerPoint cp ");
        qlString.append("  WHERE cp.customerId IN (:customerIds) ");

        Query query = this.em.createQuery(qlString.toString());
        query.setParameter("customerIds", customerIds);
        @SuppressWarnings("unchecked")
        List<CustomerPoint> points = (List<CustomerPoint>) query.getResultList();
        if (points == null || points.isEmpty()) return null;

        Map<Long, Long> currentCustomerPointMap = new HashMap<Long, Long>();
        for (CustomerPoint customerPoint : points) {
            if (currentCustomerPointMap.get(customerPoint.getCustomerId()) != null) {
                BigDecimal point = BigDecimal.valueOf(currentCustomerPointMap.get(customerPoint.getCustomerId()));
                if (PointClsType.MINUS == customerPoint.getPointCls()) {
                    point = point.subtract(BigDecimal.valueOf(customerPoint.getPoint()));
                }
                else {
                    point = point.add(BigDecimal.valueOf(customerPoint.getPoint()));
                }
                currentCustomerPointMap.put(customerPoint.getCustomerId(), point.longValue());
            }
            else {
                currentCustomerPointMap.put(customerPoint.getCustomerId(), customerPoint.getPoint());
            }
        }
        return currentCustomerPointMap;
    }

    @Override
    public long getCurrentCusotemrPoint(long customerId) {
        StringBuilder qlString = new StringBuilder();
        qlString.append(" SELECT cp ");
        qlString.append("   FROM CustomerPoint cp ");
        qlString.append("  WHERE cp.customerId = :customerId ");

        Query query = this.em.createQuery(qlString.toString());
        query.setParameter("customerId", customerId);
        @SuppressWarnings("unchecked")
        List<CustomerPoint> points = (List<CustomerPoint>) query.getResultList();
        if (points == null || points.isEmpty()) return 0;

        BigDecimal point = BigDecimal.ZERO;
        for (CustomerPoint customerPoint : points) {
            if (PointClsType.MINUS == customerPoint.getPointCls()) {
                point = point.subtract(BigDecimal.valueOf(customerPoint.getPoint()));
            }
            else {
                point = point.add(BigDecimal.valueOf(customerPoint.getPoint()));
            }
        }
        return point.longValue();
    }
}
